import sys
# import pandas as pd
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,
                             QPushButton, QLabel, QLineEdit, QFileDialog, QComboBox, QCheckBox, QTableWidget, QHeaderView, QTableWidgetItem, QTextEdit)
from ansys.fluent.core import launch_fluent  # 调用pyfluent
import os

# 导入展示结果的窗口
# from plotwindow import PlotWindow
# 定义全局变量，用于存储Fluent会话
# session = None


class FormDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    # 主函数，用于创建UI
    def initUI(self):
        # 大小
        self.resize(600, 600)
        # 创建整体垂直布局
        vbox = QVBoxLayout()
        vbox.setSpacing(20)

        # 启动Fluent的按钮
        self.launchButton = QPushButton("启动Fluent（求解器模式）", self)
        self.launchButton.clicked.connect(self.start_fluent)  # 点击按钮启动Fluent
        vbox.addWidget(self.launchButton)

        # 第一行 - 加载网格文件
        hbox1 = QHBoxLayout()
        gridFileLabel = QLabel('加载网格文件', self)
        self.gridFileLineEdit = QLineEdit(self)
        self.gridFileLineEdit.setPlaceholderText('请选择网格文件路径')
        gridFileButton = QPushButton('浏览...', self)
        gridFileButton.clicked.connect(self.browseGridFile)
        hbox1.addWidget(gridFileLabel)
        hbox1.addWidget(self.gridFileLineEdit)
        hbox1.addWidget(gridFileButton)

        # 将第一行的水平布局添加到垂直布局中
        hbox1.setSpacing(10)  # 设置水平间距
        hbox1.addStretch()
        vbox.addLayout(hbox1)

        # 第二行 - 重力加速度
        # 第二行 - 重力加速度
        # hbox2 = QHBoxLayout()
        # gravityLabel = QLabel('重力加速度', self)
        # self.xAxisComboBox = QComboBox(self)
        # self.yAxisComboBox = QComboBox(self)
        # self.zAxisComboBox = QComboBox(self)

        # 设置下拉框的默认显示项
        # self.xAxisComboBox.addItem('x轴', userData=None)
        # self.yAxisComboBox.addItem('y轴', userData=None)
        # self.zAxisComboBox.addItem('z轴', userData=None)

        # 假设加速度的值，可以根据需要修改
        # acceleration_values = ['9.81', '0', '-9.81']
        # self.xAxisComboBox.addItems(acceleration_values)
        # self.yAxisComboBox.addItems(acceleration_values)
        # self.zAxisComboBox.addItems(acceleration_values)

        # hbox2.addWidget(gravityLabel)
        # hbox2.addWidget(self.xAxisComboBox)
        # hbox2.addWidget(self.yAxisComboBox)
        # hbox2.addWidget(self.zAxisComboBox)

        # # 将第二行的水平布局添加到垂直布局中
        # hbox2.setSpacing(10)  # 设置水平间距
        # hbox2.addStretch()
        # vbox.addLayout(hbox2)

        # 第三行 - 激活能量方程
        hbox3 = QHBoxLayout()
        energyLabel1 = QLabel('激活能量方程', self)
        energyLabel2 = QLabel('湍流方程', self)
        self.energyCheckBox = QCheckBox(self)

        self.energyComboBox = QComboBox(self)

        # 假设方程有一个键值对应关系
        equations = {
            'k-kl-w': 'k-kl-w',
            'ke_realizable': 'ke_realizable',
            'kw_bsl': 'kw_bsl',
            'kw_geko': 'kw_geko',
            'kw_sst': 'kw_sst',
            'kw_standard': 'kw_standard',
        }

        # 添加选项到下拉框，并设置为禁用状态
        for key, value in equations.items():
            self.energyComboBox.addItem(value, userData=key)
        self.energyComboBox.setEnabled(False)

        # 当勾选框状态改变时，更新下拉框的启用状态
        self.energyCheckBox.stateChanged.connect(self.toggleEnergyComboBox)

        hbox3.addWidget(energyLabel1)
        hbox3.addWidget(self.energyCheckBox)
        hbox3.addWidget(energyLabel2)
        hbox3.addWidget(self.energyComboBox)

        # 添加按钮以触发viscous_q方法
        self.viscousButton = QPushButton("设置湍流方程", self)
        self.viscousButton.clicked.connect(self.viscous_q)  # 按钮触发viscous_q方法
        vbox.addWidget(self.viscousButton)

        # 将第三行的水平布局添加到垂直布局中
        hbox3.setSpacing(10)  # 设置水平间距
        hbox3.addStretch()
        vbox.addLayout(hbox3)

        # 第四行 - 识别流体边界和边界条件
        hbox4 = QHBoxLayout()
        boundaryButton = QPushButton('识别流体边界', self)
        boundaryButton.clicked.connect(self.loadBoundaryConditions)
        boundaryLabel = QLabel('边界条件', self)
        self.boundaryLineEdit = QLineEdit(self)
        self.boundaryLineEdit.setPlaceholderText('请导入边界条件表格')
        hbox4.addWidget(boundaryButton)
        hbox4.addWidget(boundaryLabel)
        hbox4.addWidget(self.boundaryLineEdit)
        vbox.addLayout(hbox4)

        # 第五行 - 展示Excel数据的表格
        self.boundaryTable = QTableWidget(self)
        self.boundaryTable.setColumnCount(5)  # 设置表格为5列
        self.boundaryTable.setHorizontalHeaderLabels(
            ['边界名称', '边界条件', '压力/风速/质量', '温度', '质量比'])
        self.boundaryTable.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.boundaryTable.setFixedHeight(150)
        vbox.addWidget(self.boundaryTable)

        # 第五行 - 进行初始化及案例文件上传
        hbox5 = QHBoxLayout()
        self.initCheckBox = QCheckBox('进行初始化', self)
        hbox5.addWidget(self.initCheckBox)

        caseFileLabel = QLabel('案例文件', self)
        hbox5.addWidget(caseFileLabel)

        self.caseFileLineEdit = QLineEdit(self)
        self.caseFileLineEdit.setPlaceholderText('fluent案例case文件保存路径')
        hbox5.addWidget(self.caseFileLineEdit)

        caseFileButton = QPushButton('浏览', self)
        caseFileButton.clicked.connect(self.browseCaseFile)
        hbox5.addWidget(caseFileButton)

        vbox.addLayout(hbox5)

        # 第六行 - 风速输入框
        hboxwind = QHBoxLayout()
        windSpeedLabel = QLabel('风速', self)
        self.windSpeedLineEdit = QLineEdit(self)
        self.windSpeedLineEdit.setPlaceholderText('请输入风速')
        hboxwind.addWidget(windSpeedLabel)
        hboxwind.addWidget(self.windSpeedLineEdit)
        vbox.addLayout(hboxwind)

        # 第六行 - 计算按钮与求解方法、求解步数
        hbox6 = QHBoxLayout()

        # 求解方法
        solveMethodLabel = QLabel('求解方法', self)
        self.solveMethodComboBox = QComboBox(self)
        self.solveMethodComboBox.addItems(
            ['SIMPLE', 'PISO', 'SIMPLEC', 'Coupled'])  # 示例方法
        self.solveMethodComboBox.currentIndexChanged.connect(self.solveMethod)
        hbox6.addWidget(solveMethodLabel)
        hbox6.addWidget(self.solveMethodComboBox)

        # 求解步数
        solveStepsLabel = QLabel('求解步数', self)
        self.solveStepsComboBox = QComboBox(self)
        self.solveStepsComboBox.addItems(
            [str(x) for x in range(1, 101)])  # 1到100步
        hbox6.addWidget(solveStepsLabel)
        hbox6.addWidget(self.solveStepsComboBox)

        # 添加一定间隔，使左右两侧分隔开
        hbox6.addStretch()

        # 计算按钮
        calculateButton = QPushButton('计算', self)
        calculateButton.clicked.connect(self.start_fluent)
        hbox6.addWidget(calculateButton)

        vbox.addLayout(hbox6)

        # 按钮用于展示图形结果
        # self.showResultsButton = QPushButton("展示图形结果弹窗", self)
        # self.showResultsButton.clicked.connect(self.show_results)  # 绑定到展示结果的方法
        # self.showResultsButton.setEnabled(False)  # 初始为禁用状态
        # self.layout.addWidget(self.showResultsButton)

        # 第七行 - 结果文件展示
        hbox7 = QHBoxLayout()
        resultFileLabel = QLabel('结果文件', self)
        self.resultFileLink = QLabel(
            '<a href="#">查看结果文件</a>', self)  # 使用超链接显示结果文件
        self.resultFileLink.setOpenExternalLinks(True)  # 允许外部链接打开
        hbox7.addWidget(resultFileLabel)
        hbox7.addWidget(self.resultFileLink)
        vbox.addLayout(hbox7)

        # 第八行 - 控制台输出
        consoleOutputLabel = QLabel('控制台输出', self)
        consoleOutputLabel.setAlignment(Qt.AlignCenter)  # 标签居中
        self.consoleOutput = QTextEdit(self)
        self.consoleOutput.setFixedHeight(300)
        self.consoleOutput.setReadOnly(True)  # 设置为只读，仅用于显示
        vbox.addWidget(consoleOutputLabel)
        vbox.addWidget(self.consoleOutput)

        # 设置整体布局
        self.setLayout(vbox)
        self.setWindowTitle('复杂地形风速仿真模拟')

    # 功能函数开始
    def start_fluent(self):
        global session  # 确保可以修改全局变量

        # 启动Fluent求解器模式
        if session is None:
            session = launch_fluent(
                precision="double", processor_count=2, ui_mode="gui", mode="meshing")
            self.consoleOutput.append("Fluent已启动！")
        else:
            self.consoleOutput.append("Fluent已在运行中。")

    def browseGridFile(self):
        # 打开文件选择对话框
        options = QFileDialog.Options()
        gridFilePath, _ = QFileDialog.getOpenFileName(
            self, "选择网格文件", "", "All Files (*);;Text Files (*.txt)", options=options)
        if gridFilePath:
            # 显示选择的文件路径
            self.gridFileLineEdit.setText(gridFilePath)
        # 需要获取文件内容

    def toggleEnergyComboBox(self, state):

        # 如果勾选框被选中，启用下拉框，否则禁用
        if state == Qt.Checked:
            self.energyComboBox.setEnabled(True)
            # session.tui.define.models.energy(
            #     'yes', ',', ',', ',', ',')  # 激活能量方程
            self.consoleOutput.append("能量方程已激活！")  # 在控制台输出反馈
        else:
            self.energyComboBox.setEnabled(False)

    # 第四行函数

    def loadBoundaryConditions(self):
        # 打开文件选择对话框
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(
            self, "选择边界条件表格", "", "Excel Files (*.xlsx)", options=options)
        if fileName:
            # 显示选择的文件路径
            self.boundaryLineEdit.setText(fileName)
            # 读取Excel文件内容
            df = pd.read_excel(fileName)
            # 将内容展示在表格中
            self.populateTable(df)

    def populateTable(self, dataframe):
        self.boundaryTable.setRowCount(len(dataframe.index))
        for row in dataframe.itertuples():
            for col_index, value in enumerate(row[1:]):
                self.boundaryTable.setItem(
                    row.Index, col_index, QTableWidgetItem(str(value)))

    # 第5行函数
    def browseCaseFile(self):
        # 打开文件选择对话框以选择案例文件
        options = QFileDialog.Options()
        caseFileName, _ = QFileDialog.getOpenFileName(
            self, "选择fluent案例case文件", "", "Case Files (*.case)", options=options)
        if caseFileName:
            self.caseFileLineEdit.setText(caseFileName)

    # 湍流方程计算
    def viscous_q(self):
        if self.energyComboBox.currentText() == 'k-kl-w':
            session.tui.define.models.viscous.k_kl_w('yes')
            self.consoleOutput.append("湍流方程 k-kl-w 已设置！")
        elif self.energyComboBox.currentText() == 'ke_realizable':
            session.tui.define.models.viscous.ke_realizable('yes')
            self.consoleOutput.append("湍流方程 ke_realizable 已设置！")
        elif self.energyComboBox.currentText() == 'kw_bsl':
            session.tui.define.models.viscous.kw_bsl('yes')
            self.consoleOutput.append("湍流方程 kw_bsl 已设置！")
        elif self.energyComboBox.currentText() == 'kw_geko':
            session.tui.define.models.viscous.kw_geko('yes')
            self.consoleOutput.append("湍流方程 kw_geko 已设置！")
        elif self.energyComboBox.currentText() == 'kw_sst':
            session.tui.define.models.viscous.kw_sst('yes')
            self.consoleOutput.append("湍流方程 kw_sst 已设置！")
        elif self.energyComboBox.currentText() == 'kw_standard':
            session.tui.define.models.viscous.kw_standard('yes')
            self.consoleOutput.append("湍流方程 kw_standard 已设置！")
    # 求解方法

    def solveMethod(self):
        current_method = self.solveMethodComboBox.currentText()  # 获取下拉框当前选项
        if current_method == 'SIMPLE':
            session.solution.methods.p_v_coupling.flow_scheme = 'SIMPLE'
            self.consoleOutput.append("求解方法已设置为 SIMPLE")
        elif current_method == 'PISO':
            session.solution.methods.p_v_coupling.flow_scheme = 'PISO'
            self.consoleOutput.append("求解方法已设置为 PISO")
        elif current_method == 'SIMPLEC':
            session.solution.methods.p_v_coupling.flow_scheme = 'SIMPLEC'
            self.consoleOutput.append("求解方法已设置为 SIMPLEC")
        elif current_method == 'Coupled':
            session.solution.methods.p_v_coupling.flow_scheme = 'Coupled'
            self.consoleOutput.append("求解方法已设置为 Coupled")

    # 第6行

    def calculate(self):
        # 获取所有输入框的值
        gridFilePath = self.gridFileLineEdit.text()
        # xAxis = self.xAxisComboBox.currentText()
        # yAxis = self.yAxisComboBox.currentText()
        # zAxis = self.zAxisComboBox.currentText()
        # boundaryFilePath = self.boundaryLineEdit.text()
        # caseFilePath = self.caseFileLineEdit.text()
        # solveMethod = self.solveMethodComboBox.currentText()
        solveSteps = self.solveStepsComboBox.currentText()
        #
        # # 打印所有收集到的值
        # print("加载网格文件路径:", gridFilePath)
        # print("X轴重力加速度:", xAxis)
        # print("Y轴重力加速度:", yAxis)
        # print("Z轴重力加速度:", zAxis)
        # print("边界条件文件路径:", boundaryFilePath)
        # print("案例文件路径:", caseFilePath)
        # print("求解方法:", solveMethod)
        # print("求解步数:", solveSteps)
        #
        # # 假设计算结果
        # resultFilePath = '/path/to/result.file'  # 假设的结果文件路径
        # self.resultFileLink.setText(f'<a href="file:///{resultFilePath}">查看结果文件</a>')  # 更新链接
        # self.consoleOutput.append("计算完成，结果文件已保存。")  # 在控制台输出中显示信息

        # 在这里调用计算方法
        # placeholder_for_calculation_method()

        # 获取必要参数
        mesh_file = gridFilePath  # 网格文件路径
        # TODO: 风速从哪里来
        wind_speed = self.windSpeedLineEdit.text()  # 风速
        iteration_steps = int(solveSteps)  # 迭代步数

        # 启动Fluent求解器
        solver = launch_fluent(
            precision="double", processor_count=4, mode="solver", show_gui=True)

        # 读取网格文件
        solver.tui.file.read_case(case_file_name=mesh_file)

        # 设置能量方程
        solver.tui.define.models.energy("no", ", ", ", ", ", ", ", ")

        # 设置边界条件
        solver.tui.define.boundary_conditions.velocity_inlet(
            "inlet",
            "no",
            "no",
            "yes",
            "yes",
            "no",
            wind_speed,  # 动态传参
            "no",
            "0",
            "no",
            "no",
            "yes",
            "5",
            "10",
        )

        # 其他求解器设置
        solver.tui.solve.monitors.residual.plot("yes")
        solver.tui.solve.initialize.hyb_initialization()

        # 设置迭代步数并开始求解
        solver.tui.solve.iterate(iteration_steps)  # 动态传参

        result_data_path = "output_data.dat"
        solver.tui.file.write_data(result_data_path)
        # 保存结果
        # solver.tui.file.write_case("xxxx.cas.h5")  # 根据需求动态设置保存路径
        # solver.tui.file.write_data("xxxx.dat.h5")

        # 输出求解器完成的信息
        self.consoleOutput.append("求解完成！结果已保存。")

        # 退出Fluent
        solver.exit()

        # 这里是读取结果数据的代码
        # 读取结果数据
        simulation_results = self.read_results(result_data_path)
        return simulation_results

    def read_results(self, filepath):
        # 这是一个示例函数，用于从 Fluent 的结果文件中读取数据
        # 实际实现需要根据你保存的数据格式来编写
        data = []
        with open(filepath, 'r') as file:
            for line in file:
                # 假设每行是时间步和对应的某个结果值
                step, value = map(float, line.split())
                data.append((step, value))
        return data

    def start_fluent(self):
        # 从 calculate 方法获取仿真结果数据
        simulation_data = self.calculate()
        # 在弹窗中展示图表
        self.plotWindow.plot(simulation_data)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = FormDemo()
    ex.show()
    sys.exit(app.exec_())
